// scratch作品状态文件
import keyMirror from 'keymirror';
// 从服务器加载作品
const SET_LESSON_ID = 'project/SET_LESSON_ID';
const SET_PROJECT_ID = 'project/SET_PROJECT_ID';
const DONE_FETCHING_WITH_ID = 'project/DONE_FETCHING_WITH_ID';
const DONE_LOADING_VM_WITH_ID = 'project/DONE_LOADING_VM_WITH_ID';
// 从本机加载作品。作品状态：新作品
const START_LOADING_VM_FILE_UPLOAD = 'project/START_LOADING_VM_FILE_UPLOAD';
const DONE_LOADING_VM_FILE_UPLOAD = 'project/DONE_LOADING_VM_FILE_UPLOAD';
// 复制、改编作品：作品状态：新作品
const COPY_PROJECT = 'project/COPY_PROJECT';
// 保存作品到服务器
const START_UPDATING = 'project/START_UPDATING';
const DONE_UPDATING = 'project/DONE_UPDATING';
// 保存新作品成功后，把服务器返回的新作品ID设置为当前作品ID
const SET_PROJECT_NEW_ID = 'project/SET_PROJECT_NEW_ID';

const SET_PROJECT_TITLE = 'project/SET_PROJECT_TITLE'; // 设置作品名称并保存到服务器
const SET_PROJECT_SHARE = 'project/SET_PROJECT_SHARE'; // 分享作品并把分享状态保存到服务器

const SET_PROJECT_CHANGED = 'project/SET_PROJECT_CHANGED'; // 作品已改变：如源代码被修改
const START_ERROR = 'project/START_ERROR';
const RETURN_TO_SHOWING = 'project/RETURN_TO_SHOWING';
// 作品的各种状态
const LoadingState = keyMirror({
    ERROR: null,
    NOT_LOADED: null,

    FETCHING_WITH_ID: null,
    LOADING_VM_WITH_ID: null,
    SHOWING_WITH_ID: null, // 显示的正常作品：用户自己的作品或是别人的作品

    MANUAL_UPDATING: null, // 开始手动更新作品
    LOADING_VM_FILE_UPLOAD: null // 从本机加载作品时的状态
});
const LoadingStates = Object.keys(LoadingState);
// 默认作品，也是新建作品时的模板
// 新建、上传、复制、改编的作品，设定为没有ID的作品
// 从服务器动态获取的优点：
// 1、可以在不同时间，呈现不同的默认作品；比如：中秋节时，设置一个中秋节特色的作品为默认作品；
// 2、可以为不同机构做不同的默认作品；
const defaultProjectId = 0;
const initialState = {
    loadingState: LoadingState.NOT_LOADED, // 当前作品状态
    error: null,

    // 设置projectChanged==true的条件：
    // 1、作品源代码被更改
    // 2、新建、复制、改编、上传的作品（同时，设置作品ID=0、作品作者ID=0）
    projectChanged: false, // 作品是否已改变，即为是否需要保存

    // 作品部分=====================================================
    projectData: {}, // 整个作品的JSON格式的源代码
    projectId: 0, // 作品ID
    title: '', // 作品名称
    authorId: 0, // 作者ID
    state: 0, // 0：未发布；// 1：已发布；// 2：已开源；（开源的必须发布）
    
    // 作业部分=====================================================
    // 有课程卡时：
    // 无作业ID：设置为作业
    // 有作业ID：作业ID != 当前作品ID：1、设置为作业；2、打开原作业
    // 作业ID == 当前作品ID：提示：作品为本课作业
    teacher_id: 0, // >0时，表示作品为作业，并由老师打开
    lesson_id: 0, // >0时，课时卡对应的课时ID
    
    card_count: 0 // >0时，表示有课时卡
};

const reducer = function (state, action) {
    if (typeof state === 'undefined') state = initialState;

    switch (action.type) {
        case SET_LESSON_ID://设置准备加载课时卡的课时ID
            // ID没变：直接返回原状态
            if (state.lesson_id === action.lessonId) {return state;}

            // ID变了        
            return Object.assign({}, state, {lesson_id: action.lessonId});
        case SET_PROJECT_ID://设置准备加载的作品ID
            if (state.loadingState === LoadingState.NOT_LOADED || state.loadingState === LoadingState.SHOWING_WITH_ID) {
                // 作品ID没变：直接返回原状态，阻止重新加载project
                if (state.projectId>0 && state.projectId === action.projectId) {return state;}

                // 作品ID变了：设置状态为FETCHING_WITH_ID，即通知对应组件请求新的project数据        
                return Object.assign({}, state, {
                    loadingState: LoadingState.FETCHING_WITH_ID,
                    projectId: action.projectId
                });
            }
        case DONE_FETCHING_WITH_ID://对已经下载好了作品，做数据配置
            if (state.loadingState === LoadingState.FETCHING_WITH_ID) {
                // 已经获取到作品数据，开始加载到VM中：LOADING_VM_WITH_ID
                if (action.projectData.teacher_id){
                    state.teacher_id = action.projectData.teacher_id;
                }

                return Object.assign({}, state, {
                    loadingState: LoadingState.LOADING_VM_WITH_ID,
                    projectChanged: action.projectData.id==defaultProjectId,//自动设置改变标签

                    //作品ID：如果是默认作品，则Id也设置为0，与复制、改编、上传的作品被保存前的Id统一为0
                    projectId: action.projectData.id==defaultProjectId?0:action.projectData.id,
                    projectData: action.projectData.src,//作品JSON源代码
                    authorId: action.projectData.authorid,//作者ID
                    state:action.projectData.state,//分享：是否分享
                    title:action.projectData.title,//作品名称

                    //作业相关部分
                    teacher_id:state.teacher_id,
                });
            }
        case DONE_LOADING_VM_WITH_ID://已经加载到VM，设置作品状态为SHOWING_WITH_ID
            if (state.loadingState === LoadingState.LOADING_VM_WITH_ID) {
                return {...state, loadingState: LoadingState.SHOWING_WITH_ID};
            }
        case COPY_PROJECT://复制作品：修改作品ID=0、作品作者ID=0
            if (state.loadingState === LoadingState.SHOWING_WITH_ID) {
                return Object.assign({}, state, {
                    projectChanged: true,//自动设置改变标签
                    projectId: 0,//作品ID
                    authorId: 0,//作者ID
                    state:0,//分享：是否分享
                    
                    /*复制作品时，如果打开的是作业示例，一定不能清除下面的变量
                    *teacher_id:0,
                    */
                });
            }
        case START_UPDATING://开始更新
            if (state.loadingState === LoadingState.SHOWING_WITH_ID) {
                return {...state, loadingState: LoadingState.MANUAL_UPDATING};
            }
        case DONE_UPDATING://上传更新成功
            if (state.loadingState === LoadingState.MANUAL_UPDATING) {
                return {...state, loadingState: LoadingState.SHOWING_WITH_ID};
            }
        case SET_PROJECT_NEW_ID://设置刚被新建保存到服务器的作品id及作者ID
            return {...state, authorId:action.authorId, projectId: action.projectId};

        case START_LOADING_VM_FILE_UPLOAD://加载本地作品
            if (state.loadingState === LoadingState.SHOWING_WITH_ID) {
                return {...state, loadingState: LoadingState.LOADING_VM_FILE_UPLOAD};
            }
        case DONE_LOADING_VM_FILE_UPLOAD://加载本地作品完毕
            if (state.loadingState === LoadingState.LOADING_VM_FILE_UPLOAD) {
                return Object.assign({}, state, {
                    loadingState: LoadingState.SHOWING_WITH_ID,
                    
                    projectChanged: true,//自动设置改变标签
                    projectId: 0,//作品ID
                    authorId: 0,//作者ID
                    state:0,//分享：是否分享
                    title: action.title,//作品名称
                    
                    error: null,
                    projectData: {}//整个作品的JSON格式的源代码  
                    
                    /*加载作品时，如果打开的是作业示例，一定不能清除下面的变量
                    *teacher_id:0,
                    */
                });
            }

        case RETURN_TO_SHOWING:
            return {...state, loadingState: LoadingState.SHOWING_WITH_ID};
        case SET_PROJECT_TITLE://修改作品名称
            return {...state, title: action.title};
        case SET_PROJECT_SHARE://修改作品分享状态
            return {...state, state: action.state};
        case SET_PROJECT_CHANGED://设置作品是否需要被保存
            //console.warn("BLJ：设置作品是否需要被保存"+action.changed);
            return {...state, projectChanged: action.changed};
        case START_ERROR:
                // fatal errors: there's no correct editor state for us to show
                if ([
                    LoadingState.FETCHING_WITH_ID,
                    LoadingState.LOADING_VM_WITH_ID
                ].includes(state.loadingState)) {
                    return initialState
                }
                // non-fatal errors: can keep showing editor state fine
                if ([
                    LoadingState.MANUAL_UPDATING
                ].includes(state.loadingState)) {
                    return Object.assign({}, state, {
                        loadingState: LoadingState.SHOWING_WITH_ID,
                        error: action.error
                    });
                }
       // default: return state;
    }
    return state;
};
const projectError = error => ({type: START_ERROR,error: error});
const getIsError = loadingState => (loadingState === LoadingState.ERROR);
const getIsFetchingWithId = loadingState => (loadingState === LoadingState.FETCHING_WITH_ID);
const getIsLoadingWithId = loadingState => (loadingState === LoadingState.LOADING_VM_WITH_ID);
const getIsShowingProject = loadingState => (loadingState === LoadingState.SHOWING_WITH_ID);
//复制作品
const copyProject = () => ({type: COPY_PROJECT});
//启动保存作品到服务器
const updateProject = () => ({type: START_UPDATING});
//获取是否正在保存到服务器的状态
const getIsUpdating = loadingState => ( loadingState === LoadingState.MANUAL_UPDATING );
//作品保存完毕
const doneUpdatingProject = () => ({type: DONE_UPDATING});
//加载作品
const onLoadedProject = (loadingState, success, projectTitle) => {
    // failed to load project; just keep showing current project
    if (!success) { return {type: RETURN_TO_SHOWING}; }

    switch (loadingState) {
    case LoadingState.LOADING_VM_WITH_ID://加载服务器作品
        return {type: DONE_LOADING_VM_WITH_ID};
    case LoadingState.LOADING_VM_FILE_UPLOAD://加载本地作品
        return {type: DONE_LOADING_VM_FILE_UPLOAD, title:projectTitle};
    default:
        return;
    }
};
//开始加载本地作品
const requestProjectUpload = () => ({type: START_LOADING_VM_FILE_UPLOAD});
//判断是否正在加载本地作品
const getIsLoadingUpload = loadingState => (loadingState === LoadingState.LOADING_VM_FILE_UPLOAD);
//设置课时ID：可以获取对应的课时卡
const setLessonId = id => ({type: SET_LESSON_ID, lessonId: id});
//设置作品ID：即将加载的作品
const setProjectId = id => ({type: SET_PROJECT_ID,projectId: id});
//设置作品JSON源代码
const setProjectData = (projectData) => ({type: DONE_FETCHING_WITH_ID,projectData: projectData});
//修改作品名称
const setProjectTitle = title => ({type: SET_PROJECT_TITLE, title: title});
//修改作品分享状态
const setProjectShare = state => ({type: SET_PROJECT_SHARE, state: state});

//设置作品状态为：已改变
const setProjectChanged = () => ({type: SET_PROJECT_CHANGED,changed: true});
//设置作品状态为：未改变
const setProjectUnchanged = () => ({type: SET_PROJECT_CHANGED,changed: false});
//设置新保存作品的作品id及作者Id
const setProjectNewId = (authorId, projectId) => ({type: SET_PROJECT_NEW_ID, authorId:authorId, projectId:projectId});

export {
    reducer as default,
    initialState as projectStateInitialState,
    defaultProjectId,
    LoadingState,
    LoadingStates,

    projectError,
    getIsError,
    getIsFetchingWithId,
    getIsLoadingWithId,
    getIsShowingProject,
    copyProject,
    updateProject,
    getIsUpdating,
    doneUpdatingProject,
    onLoadedProject,

    requestProjectUpload,
    getIsLoadingUpload,
    
    setLessonId,
    setProjectId,
    setProjectData,
    setProjectTitle,
    setProjectShare,

    setProjectChanged,
    setProjectUnchanged,
    setProjectNewId,
};
